國內飲料大廠有句廣告標語:「Try It!」筆者還蠻喜歡的。
圖片截自網路
從小在父母的保護下長大,一直到自己出國,到人生地不熟的地方讀書,真正遭遇的挫折了,這才發現,以前父母幫我做的事、舖的路,雖然很好很完整,但也不小心使我少了自己探索學習的機會。
這樣的體悟,後來對我的影響很大。往後我再也不相信世上有「最佳解」這件事。我要求我自己與我的團隊,工作上遇到什麼問題,不能坐著等老闆或主管來告訴我他們希望我們做什麼。工作上有問題,困擾的是我們,首先應該要是我們自己去找解法,而找到解法後也沒有人能確定解法好不好,只能去「試看看」,自己感受一下。
說不定到最後我們能發展出一套模式,可以更廣泛地應用在每天從事的軟體開發上,那就會成為我們專屬的,自成一格的「軟體工程」模式了。
還記得我們在一開始時有聊到單元測式與敏捷開發的關係嗎?今天要來更深入探討這件事情。或者更精準地說,我們要聊的是「軟體工程」。
筆者蠻喜歡 Extreme Programming 這本書的。作者 Kent Beck 在書中提出了許多他建議的軟體工程實踐,而我認為書名「Extreme」這個字真的下得很好,因為你在工作上不斷精進各種軟硬實力,不斷改善所有你可以改善的事情,認真把「Programming」這件事做到極致,其實也就差不多是書中形容的那樣了。有人將這些實踐分門別類,畫成下圖的樣子:
圖片截自:12 Core Practices In Extreme Programming XP
在上圖中,最內層黃色的是「工程實踐」,中間橘色的是「團隊協作」,最外層的是「流程改善」。
TDD 被放在這圖中的最內層,旁邊擺著的是重構、簡單設計,與結對編程。這代表什麼意思?就是你第一步要先把內層的四件事做好了,你做外圈才會順暢,才有意思。
那你連 Unit Test 都沒有,你跟人家一來就要搞 Scrum,玩「估算點數」,搞「持續部署」,是在忙什麼?
有人野心很大,請了一個「名師」來講了一個三天的 session,有人阮囊羞澀,買了一本書大家分著讀完,無論如何,總之結束後他們就開始「導入 XP」的所有實踐,期待能一戰成名,自此平步青雲,一帆風順。
可想而知,都是掛掉比較多。
如果這些人真的有把書讀懂,他們肯定在書中有讀到作者本人的建議:「你不太可能一口氣同時開始所有實踐,那會扼殺一個團隊的所有精力。」是的,Kent Beck 建議我們先分析現在團隊遇到最棘手的問題,然後一個一個實踐慢慢引入。」
所以,不要「導入」XP,要在適當的時機,拿來解決工作上的瓶頸。
有道是 Scrum 三本柱:探索、調適、透明化。筆者曾經參加過 LeSS 名師呂毅的培訓課程,對其中的一個「野雁南飛」的故事印象深刻。
在北美,冬天是非常冷的,因此,當地的野雁在靠近冬天時,會聚在一起商討對策,決定一個良辰吉日,找一塊地靈人傑的好地方,由資深的野雁當 Leader,數到三就一起往目的地飛去。飛的時候還不忘排好隊,由 Leader 決定今天是要飛「人字型」還是「一字型」。
圖片截自 kknews
你不是真的相信,對吧?
以上當然是我瞎掰的。真正的野雁,在出發前並不會知道這次旅行的目的地在哪,牠們也沒有所謂的「Leader」來決定事情。好,牠們是會有一個 Leader,不過不是拿來決定事情的,只是飛在最前頭,好讓其他同伴對齊而已。
那麼,野雁怎麼知道要飛去哪兒過冬呢?如前所述,牠們不知道。雖然不知道,但牠們還是有個「共同目標」:要找到「溫暖、有食物,且安全的地方」。
於是,有了共同目標後,牠們就先討論一下,但現在對於冬天的了解還太少,只知道往南應該比較溫暖,於是就先往南飛一段試試。
飛一小段後,停下來休息一下,並同時觀察四周,看看是否有比較溫暖、有沒有足夠的食物,附近天敵多不多。好像有比較好,但還差一點,於是調整一下方向,再重新上路,尋找下一個地點。
再飛一小段後,再停下來休息一下,並同時觀察四周,看看是否更溫暖、食物更多,附近天敵更少了,然後,重複以上步驟,直到找到一個棲息地,氣候、食物、安全性都滿足了大家的需求,就停下來過冬,等待春天的到來。
以上,就是筆者在呂毅老師的 CSM 課堂上,聽過的北美野雁南遷過冬的故事。
「你到底在講什麼啊?」
阿彌陀佛,這位施主,我在講 Scrum 啊!這不是野雁的故事,是 Scrum 的故事啊!
圖片截自電影 - 達摩
跟 XP 一樣,很多人都是用自己的方法學習了以後(或是不學習,直接只看標題),就想要來工作場合「導入 Scrum」,期待能一口氣解決工作上所有問題,變成一間「很敏捷」的公司。
可惜的是,這種也是掛掉比較多。
如果大家有真的把 Scrum 搞懂,應該會知道,Scrum 每個 Sprint 結束後,要得到的是「Potentially Shippable」的功能。什麼是「Potentially Shippable」?這我們先前聊過了,就是要「幾乎可以上線」,也就是要通過測試。隨著產品長大,這個測試的涵蓋範圍就會越來越大。這時如果你只仰賴 QA 的人工測試,只是幫 QA 不斷加工作而已,對 Scrum 的「探索」與「調適」一點幫助都沒有,甚至 QA 就只測部份功能了,這也傷害了產品品質的「透明度」。總之沒有自動化單元測試的 Scrum,對 QA 與或老闆來說,還不如你一口氣做完,QA 一口氣測完,老闆一口氣拿出去賣來得方便。
所以,不要「導入」Scrum,要在適當的時機,拿來解決工作上的瓶頸。
筆者出社會的第一份工作,是在一間德商的台灣辦公室,從事 Ruby 的開發。那時的部署政策,是「嚴禁在產線下部署指令」的。他們規定每個 RD 都要在自己電腦上裝 VM,裝跟產線一樣的 OS 與 DB,從環境安裝、資料庫建置、程式碼下載、資料表的創建,全部都要用 shell script 腳本執行,而且腳本一定要版控,所以從 RD、預產線環境,一路到產線,所有的部署、退版、重新安裝、資料表調整,全部都要以「執行受版控腳本」的方式來進行,而且「每個人都要用同一套腳本」。
在那個 Git、Docker 還沒紅到台灣來,k8s 也還沒問世的年代,我個人認為那間公司能做成這樣,算是很厲害了。
後來進到台中一間當時還蠻大間的電商,因緣際會下認識了Ansible,自此瘋狂愛上這位新朋友,它幾乎能做到以前寫 shell script 能做到的所有事情,除了一樣可以版控,在多環境多機器的控制上,比以前的 shell script 方便很多。使用了 Ansible 以後,每當要聯合更版時,我們總是 5 分鐘搞定,而隔壁 Team 還在那邊忙著包版、寫文件、手動測試、退版修 bug。那感覺還真不錯,不為什麼,就是我一直就很懶得做這麼匆忙又趕的事情。
後來又認識了自動化界有名的 Jenkins 大叔,我發現他除了主動觸發,還可以排程與 Hook 觸發我需要的自動測試、打包、以及指定環境的部署,這時再加上原有的 Ansible 來與 Jenkins 一搭一唱,簡直惺惺相惜情不自禁!
圖片截自網路
當然後來還有一些跟 Docker、ELK、k8s、GCP、Slack 機器人…等邂逅的浪漫故事,礙於篇幅就先省略了。
後來才知道,這些就是人家說的 DevOps 的其中一部分啊(雖然只有一小部分)!但知道這個名詞時已經是很久以後的事了。我只知道遇到問題我就想找方法解決,至於他潮不潮,上不上太空,我倒無所謂,我只要能「優雅一點地」解決我手上殺豬公的問題就好。
其實筆者是一個很懶的人。已經有好幾年,我與我的團隊,在「push」完程式後,後面的事都不用做了,幾分鐘後訊息自然會發到大家手機上,有問題到時候就知道了。我們決定把那些重複枯燥的事丟給機器做,是為了省下時間做機器做不到的事:設計與重構。你說,沒有足夠的單元測試,誰敢「放手」成這樣?
所以,不要「導入」CI/CD 與 DevOps,要在適當的時機,拿來解決工作上的瓶頸。
曾經,筆者也是會寫出「As a 用戶,I Want a 註冊功能,so that I can 註冊」這種為賦新詞強說愁的 User Story 的人。直到有一天,RD 在回顧會議上,抱怨我的 User Story 他們看不懂,這時我才發現 User Story 不該是一種文件,而應該是一種「媒介」。
什麼意思?
如果我現在跟各位讀者說:「把不起妹妹就巴頭」,各位應該只想到那個搞笑短片,但是如果跑去跟我們團隊講,大家都會告訴你,那是我們系統一個功能的代號。這是因為這句話曾經在團隊內引起很熱烈的討論,而且我們為此想了一個很特別的 Solution。因此「把不起妹妹就巴頭」就成了我們團隊回想起這個系統功能的溝通「媒介」。
User Story 也該如此。說到底,當初大家究竟是為了什麼才要開始寫 User Story 的?十有八九是為了傳統的 Spec 讀起來沒有共鳴,不容易理解吧?既然如此,那換成 User Story 後,如果還是照本宣科,拿著 Solution 來回推「使用者」的故事,那這個故事根本不會有共鳴,根本無法幫助理解,還不如不寫。
「現在的網頁,註冊要填十項資料,像智障一樣,用戶非常不爽!」
這種 User Story 是否讀起來比較能有共鳴呢?筆者隔著螢幕都能感受到用戶的怒氣呢!這下修改起來,方向就清楚多了吧!
這跟單元測試有什麼關係?
有啊!User Story 寫得好,場景清楚,測項自然就好列,功能自然就不容易做錯啊!而且不只單元測試,能設身處地為使用者著想的 RD,開發出來的程式是會難用到哪去,你說是吧?
所以,不要「導入」User Story,要在適當的時機,拿來解決工作上的瓶頸。
在寫這篇時,其實筆者心情是複雜的。明明 Scrum 是這麼好的東西,卻被一些不明究理的人瞎弄,害大家誤會 Scrum 以為它沒用。以上的 Scrum 可代入近年流行過的其他 Buzz Words。
有人曾經問我怎麼「導入」單元測試,怎麼說服老闆給我時間寫測試、寫 Ansible 設定、將產線服務容器化的,我實在是覺得這些問題很難回答。但後來想一想,又好像很好回答:「我從來沒有跟老闆多要過時間啊!」
單元測試、重構、自動化部署、容器化,這些東西不就是設計來幫大家節省時間、降低出錯率的嗎?如果需要「更多時間」來做這些事情,不就本末倒置了嗎?
所以,我建議大家不要想著「導入」什麼酷東西,而是要多觀察、感受,看看你工作上實際遭遇到什麼問題?哪個是你目前最大的瓶頸?你手上有什麼資源可以運用?不懂的,你要花多久才能學到可以拿來試用?
這就是「模式」啊!在一個場景下,使用一個方法,解決你想解決的問題,而不是拿著路上聽到的方法就拿來亂套,因為那個方法不一定適合拿來解決你的問題啊!平底鍋很好用,拿來炸薯條也不是不行,但就是有那麼一點不方便,用起來卡卡的,效率也不高,反而要花更多時間處理善後,不是嗎?
你覺得薯條炸得太慢嗎?那就先回頭看看,你現在拿來炸薯條的,是什麼鍋吧!
「該做什麼就去做,有問題就修正。」是筆者對於軟體工程的實踐,一貫採取的態度,我也建議各位大膽地去試試。反正現在你都抱怨成這樣了,再差也不會比現在差,對吧!
謎之聲:「不做不會怎樣,做了很不一樣!」
ithelp2021